package org.vacoor.ticket.executor.defaults;

import java.io.IOException;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.vacoor.ticket.bean.param.Parameter;
import org.vacoor.ticket.exception.ExecuteException;
import org.vacoor.ticket.handler.ResultHandler;
import org.vacoor.ticket.util.HttpClientFactory;

public class DefaultExecutor {
	private static HttpClient client;

	static {
		client = HttpClientFactory.getInstance().getHttpClient();
	}

	public static <R> R execute(String url, Parameter query, String method,
						ResultHandler<R> handler) throws ExecuteException {
		HttpResponse response = null;
		String queryString = query == null ? "" : query.getQueryString();
		try {
			// 以POST方式提交数据
			if ("POST".equals(method.toUpperCase())) {
				StringEntity entity = new StringEntity(queryString, "UTF-8");
//				System.out.println(method + ",url:" + url + ",queryString:" + queryString);
				HttpPost post = new HttpPost(url);
				post.setHeader("Content-Type",
						"application/x-www-form-urlencoded;charset=UTF-8");	//中文
				post.setEntity(entity);
				post.setHeader("Referer", url);
				response = client.execute(post);
				if (handler != null) {
					return handler.handler(process(post, response));
				} else {
					post.releaseConnection();
				}
			} else {
				if (!"".equals(queryString)) {
					url += (url.contains("?") ? "&" : "?") + queryString;
				}
//				System.out.println(method + ",url:" + url);
				HttpGet get = new HttpGet(url);
				get.setHeader("Referer", url);
				response = client.execute(get);
				if (handler != null) {
					return handler.handler(process(get, response));
				} else {
					get.releaseConnection();
				}
			}
		} catch (ClientProtocolException e) {
			throw new ExecuteException(e.fillInStackTrace());
		} catch (IOException e) {
			throw new ExecuteException(e.fillInStackTrace());
		}
		return null;
	}

	private static byte[] process(HttpRequestBase req, HttpResponse rsp)
			throws IllegalStateException, IOException {
		byte[] result = null;
		int state = rsp.getStatusLine().getStatusCode();
		// 如果页面重定向
		if ((state == HttpStatus.SC_MOVED_PERMANENTLY)
				|| (state == HttpStatus.SC_MOVED_TEMPORARILY)
				|| (state == HttpStatus.SC_SEE_OTHER)
				|| (state == HttpStatus.SC_TEMPORARY_REDIRECT)) {
			String newUrl = "";
			// 获取重定向的目标(这里取最后一个)
			Header header = rsp.getLastHeader("Location");
			if (header != null) {
				newUrl = header.getValue(); // 获得跳转页面地址
			}
			// 否则跳转首页
			if (newUrl == null || "".equals(newUrl)) {
				header = rsp.getLastHeader("Host");
				if (header != null) {
					newUrl = header.getValue();
				}
				newUrl += newUrl.endsWith("/") ? "" : "/";
			}
			// 释放之前连接
			req.releaseConnection();
			HttpGet get = new HttpGet(newUrl);
			get.setHeader("Referer", newUrl);
			rsp = client.execute(get);
			state = rsp.getStatusLine().getStatusCode();
			req = get;
		}
		if (state == HttpStatus.SC_OK) {
			Header[] cs = rsp.getHeaders("Set-Cookie");
			for (Header c : cs) {
				System.out.println(c.getValue());
//				String code = "document.cookie='" + c.getValue().substring(0,c.getValue().indexOf(";")) + "'";
//				System.out.println(code);
			}
			result = EntityUtils.toByteArray(rsp.getEntity());
			req.releaseConnection();
		} else {
			new RuntimeException("无法连接到服务器");
			System.exit(-1);
		}
		return result;
	}
}
